package com.pengxh.kt.lite.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF
import android.os.Handler
import android.os.Message
import android.text.TextPaint
import android.text.TextUtils
import android.util.AttributeSet
import android.view.View
import com.pengxh.kt.lite.R
import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * 圆形进度条
 */
class CircleProgressBar constructor(context: Context, attrs: AttributeSet) : View(context, attrs),
    Handler.Callback {

    private val ringRadius: Int
    private var rectF: RectF

    //控件边长
    private val viewSideLength: Int
    private val ringStroke: Int
    private val viewRect: Rect
    private lateinit var guidePaint: Paint

    private val backgroundColor: Int
    private val foregroundColor: Int
    private var text: String = ""
    private var centerX = 0f
    private var centerY = 0f
    private lateinit var backgroundPaint: Paint
    private lateinit var foregroundPaint: Paint
    private lateinit var textPaint: TextPaint

    //当前污染物测量值
    private var currentValue: String = ""

    //当前测量值转为弧度扫过的角度
    private var sweepAngle = 0f
    private val weakReferenceHandler by lazy { WeakReferenceHandler(this) }

    init {
        val type = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar)

        ringRadius = type.getDimensionPixelOffset(
            R.styleable.CircleProgressBar_cpb_ring_radius, 100.dp2px(context)
        )
        rectF = RectF(
            -ringRadius.toFloat(),
            -ringRadius.toFloat(),
            ringRadius.toFloat(),
            ringRadius.toFloat()
        )
        ringStroke = type.getDimensionPixelOffset(
            R.styleable.CircleProgressBar_cpb_ring_stroke, 10.dp2px(context)
        )
        //需要给外围刻度留位置
        viewSideLength = ringRadius + 30.dp2px(context)
        //辅助框
        viewRect = Rect(-viewSideLength, -viewSideLength, viewSideLength, viewSideLength)

        backgroundColor = type.getColor(
            R.styleable.CircleProgressBar_cpb_backgroundColor, Color.LTGRAY
        )
        foregroundColor = type.getColor(
            R.styleable.CircleProgressBar_cpb_foregroundColor, Color.BLUE
        )
        text = type.getString(R.styleable.CircleProgressBar_cpb_text).toString()

        type.recycle()
        //初始化画笔
        initPaint()
    }

    private fun initPaint() {
        guidePaint = Paint()
        guidePaint.color = Color.LTGRAY
        guidePaint.style = Paint.Style.STROKE
        guidePaint.strokeWidth = 1f.dp2px(context)
        guidePaint.isAntiAlias = true

        //背景色画笔
        backgroundPaint = Paint()
        backgroundPaint.color = backgroundColor
        backgroundPaint.style = Paint.Style.STROKE
        backgroundPaint.strokeWidth = ringStroke.toFloat()
        backgroundPaint.strokeCap = Paint.Cap.ROUND //圆头
        backgroundPaint.isAntiAlias = true

        //前景色画笔
        foregroundPaint = Paint()
        foregroundPaint.color = foregroundColor
        foregroundPaint.style = Paint.Style.STROKE
        foregroundPaint.strokeWidth = ringStroke.toFloat()
        foregroundPaint.strokeCap = Paint.Cap.ROUND //圆头
        foregroundPaint.isAntiAlias = true

        //文字画笔
        textPaint = TextPaint()
        textPaint.isAntiAlias = true
        textPaint.textAlign = Paint.Align.CENTER
        textPaint.color = Color.LTGRAY
        textPaint.textSize = 14f
    }

    //计算出中心位置，便于定位
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        centerX = (w shr 1).toFloat()
        centerY = (h shr 1).toFloat()
    }

    //计算控件实际大小
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val widthSpecMode = MeasureSpec.getMode(widthMeasureSpec)
        val widthSpecSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightSpecMode = MeasureSpec.getMode(heightMeasureSpec)
        val heightSpecSize = MeasureSpec.getSize(heightMeasureSpec)
        // 获取宽
        val mWidth: Int = if (widthSpecMode == MeasureSpec.EXACTLY) {
            // match_parent/精确值
            widthSpecSize
        } else {
            // wrap_content，外边界宽
            (viewSideLength * 2)
        }
        // 获取高
        val mHeight: Int = if (heightSpecMode == MeasureSpec.EXACTLY) {
            // match_parent/精确值
            heightSpecSize
        } else {
            // wrap_content，外边界高
            (viewSideLength * 2)
        }
        // 设置该view的宽高
        setMeasuredDimension(mWidth, mHeight)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        /**
         * 画布移到中心位置
         */
        canvas.translate(centerX, centerY)
//        drawGuides(canvas)

        //绘制进度条背景
        canvas.drawCircle(0f, 0f, ringRadius.toFloat(), backgroundPaint)

        //绘制上面百分比
        val fontMetrics = textPaint.fontMetrics
        val top = fontMetrics.top
        val bottom = fontMetrics.bottom
        if (TextUtils.isEmpty(currentValue)) {
            canvas.drawText(
                "未定义！",
                0f,
                (top + bottom) / 2,
                textPaint
            )
        } else {
            canvas.drawText(
                currentValue,
                0f,
                (top + bottom) / 2,
                textPaint
            )
        }

        //绘制下面Tip文字
        if (TextUtils.isEmpty(text)) {
            canvas.drawText(
                "未定义！",
                0f,
                -(top + bottom) * 1.5f,
                textPaint
            )
        } else {
            canvas.drawText(
                text,
                0f,
                -(top + bottom) * 1.5f,
                textPaint
            )
        }

        //绘制前景进度
        canvas.drawArc(rectF, -90f, sweepAngle, false, foregroundPaint)
    }

    /**
     * 辅助线
     * */
    private fun drawGuides(canvas: Canvas) {
        //最外层方框，即自定义View的边界
        canvas.drawRect(viewRect, guidePaint)

        //中心横线
        canvas.drawLine(
            -viewSideLength.toFloat(),
            0f,
            viewSideLength.toFloat(),
            0f,
            guidePaint
        )

        //中心竖线
        canvas.drawLine(
            0f,
            -viewSideLength.toFloat(),
            0f,
            viewSideLength.toFloat(),
            guidePaint
        )
    }

    fun setCurrentValue(value: Int) {
        currentValue = when {
            value < 0 -> "0"
            value > 100 -> "100%"
            else -> "$value%"
        }

        CoroutineScope(Dispatchers.Main).launch {
            withContext(Dispatchers.IO) {
                for (i in 0 until value) {
                    weakReferenceHandler.post(updateProgressRunnable.setProgress(i))
                    delay(10)
                }
            }
        }
    }

    private interface UpdateProgressRunnable : Runnable {
        fun setProgress(progress: Int): UpdateProgressRunnable
    }

    private val updateProgressRunnable = object : UpdateProgressRunnable {

        private var progress = 0

        override fun setProgress(progress: Int): UpdateProgressRunnable {
            this.progress = progress
            return this
        }

        override fun run() {
            sweepAngle = progress.toFloat() * 360 / 100
            invalidate()
        }
    }

    override fun handleMessage(msg: Message): Boolean {
        return true
    }
}